package org.sample.springboot.aop;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.sample.springboot.web.ErrorResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
public class ControllerExceptionHandler {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ControllerExceptionHandler.class);

	@ExceptionHandler(value = { BindException.class, MethodArgumentNotValidException.class })
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ResponseBody
	public ErrorResponse validationException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
		
		LOGGER.error("Validation error", ex);

		ErrorResponse errorResponse = new ErrorResponse();

		BindingResult bingResult = null;
		if (ex instanceof BindException) {
			BindException exception = (BindException) ex;
			bingResult = exception.getBindingResult();
		} else if (ex instanceof MethodArgumentNotValidException) {
			MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
			bingResult = exception.getBindingResult();
		}

		if (bingResult != null) {
			List<ObjectError> errors = bingResult.getAllErrors();
			// String message = ((MessageSourceResolvable) errors.get(0).getArguments()[0]).getDefaultMessage();
			// Stream.of(errors).flatMap(error -> error.)

		}	
		
		return errorResponse;
	}
	
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ResponseBody
	public ErrorResponse otherException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
		
		LOGGER.error("Unknown error", ex);
		
		ErrorResponse errorResponse = new ErrorResponse();
		errorResponse.setMessages(Arrays.asList("Unknown error"));
		return errorResponse;
	}
	
}
